package com.ruoyi.common.utils;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.UploadResult;
import com.qcloud.cos.transfer.TransferManager;
import com.qcloud.cos.transfer.TransferManagerConfiguration;
import com.qcloud.cos.transfer.Upload;
import com.ruoyi.common.config.TencentConfig;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.uuid.UUID;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
@Slf4j
public class COSUtil {

    @Autowired
    private COSClient cosClient;

    @Autowired
    private TencentConfig tencentConfig;

    //    视频后缀 校验视频格式
    public static final String VIDEO_SUFFIX = "wmv,avi,dat,asf,mpeg,mpg,rm,rmvb,ram,flv,mp4,3gp,mov,divx,dv,vob,mkv,qt,cpk,fli,flc,f4v,m4v,mod,m2t,swf,webm,mts,m2ts";
    //    图片格式
    public static final String IMG_SUFFIX = "jpg,png,jpeg,gif,svg";
    //    音频格式
    public static final String AUDIO_SUFFIX = "cda,wav,mp1,mp2,mp3,wma,vqf";


    public String uploadFile(MultipartFile file) {
        String url ="";
        try {
            url = uploadFile(Objects.requireNonNull(file.getOriginalFilename()), file.getInputStream());
        }catch (IOException e) {
            throw new ServiceException("图片上传失败");
        }
        return url;
    }

    public String uploadFile(String fileName, InputStream inputStream) {
        String url = "";
        assert fileName != null;
        int split = fileName.lastIndexOf(".");
        // 文件后缀，用于判断上传的文件是否是合法的
        String suffix = fileName.substring(split+1);
        String name = fileName.substring(0 ,split);
        fileName = tencentConfig.getPath() + name + "-" + UUID.randomUUID() + "." + suffix;
        if(IMG_SUFFIX.contains(suffix) || VIDEO_SUFFIX.contains(suffix) || AUDIO_SUFFIX.contains(suffix)) {

            // 自定义线程池大小，建议在客户端与 COS 网络充足（例如使用腾讯云的 CVM，同地域上传 COS）的情况下，设置成16或32即可，可较充分的利用网络资源
            // 对于使用公网传输且网络带宽质量不高的情况，建议减小该值，避免因网速过慢，造成请求超时。
            ExecutorService threadPool = Executors.newFixedThreadPool(32);

            // 传入一个 threadpool, 若不传入线程池，默认 TransferManager 中会生成一个单线程的线程池。
            TransferManager transferManager = new TransferManager(cosClient, threadPool);

            // 设置高级接口的配置项
            // 分块上传阈值和分块大小分别为 5MB 和 1MB
            TransferManagerConfiguration transferManagerConfiguration = new TransferManagerConfiguration();
            transferManagerConfiguration.setMultipartUploadThreshold(5*1024*1024);
            transferManagerConfiguration.setMinimumUploadPartSize(1024 * 1024);
            transferManager.setConfiguration(transferManagerConfiguration);


            String bucketName = tencentConfig.getBucketName();//储存桶名称
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileName, inputStream, new ObjectMetadata());

            try {
                Upload upload = transferManager.upload(putObjectRequest);//上传
                UploadResult uploadResult = upload.waitForUploadResult();
                uploadResult.getKey();//上传后的文件名字
            } catch (CosClientException | InterruptedException e) {
                log.error("upload file error: ", e);
                throw new ServiceException("上传文件异常");
            } finally {
                transferManager.shutdownNow(false);
            }

            url = tencentConfig.getUrl() + fileName;
        }else {
            //错误的类型，返回错误提示
            throw new ServiceException("请选择正确的文件格式");
        }

        return url;
    }


}
